package chaoyue.study.juc;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * CompletableFuture
 * CompletableFuture可以理解为FutureTask的升级版，主要是添加了多任务组合的场景
 * runAsync：处理没有返回值的任务
 * supplyAsync：处理有返回值的任务
 * 使用get可以同步阻塞获取结果（与FutureTask获取任务的方式相同）
 * 默认使用ForkJoinPool来执行提交的任务，也可以自己指定线程池来处理任务
 * 这边展示的是最基础的提交单个有返回值的任务和无返回值任务的使用方式
 */
public class CompletableFutureTest1 {
    public static void main(String[] args) throws Exception {
        // 不指定线程池，默认使用ForkJoinPool 来处理提交的任务
        // runAsync用来处理Runnable的任务
        CompletableFuture<Void> f1 = CompletableFuture.runAsync(() -> System.out.println("f1 start..." + Thread.currentThread().getName()));
        System.out.println("f1.get() = " + f1.get()); // get返回null，因为Runnable没有返回值

        // 使用自定义的线程池进行任务处理
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CompletableFuture<Void> f2 = CompletableFuture.runAsync(() -> System.out.println("f2 start..." + Thread.currentThread().getName()), threadPool);
        System.out.println("f2.get() = " + f2.get());

        // supplyAsync用来处理有返回值的任务，（Supplier是function中的接口）
        CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
            System.out.println("f3 start..." + Thread.currentThread().getName());
            return "f3 return";
        });
        System.out.println("f3.get() = " + f3.get());

        // 使用自定义的线程池进行任务处理
        CompletableFuture<String> f4 = CompletableFuture.supplyAsync(() -> {
            System.out.println("f4 start..." + Thread.currentThread().getName());
            return "f4 return";
        }, threadPool);
        System.out.println("f4.get() = " + f4.get());

        // 关闭线程池
        threadPool.shutdown();
    }
}
